package com.mokairui.threadpool.juc.cyclic_barrier;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.BrokenBarrierException;
import java.util.concurrent.CyclicBarrier;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @Description 加法, 可以重用()
 * @Author Mokairui
 * @Since 2021/10/7
 */
@Slf4j(topic = "c.cyclicBarrier")
public class CyclicBarrierDemo {
    public static void main(String[] args) {
        // 线程数要和 下面的 parties 达成一致, 比如循环提交 task1, task2 则就可能是第一次的task1 和 第二次的 task1
        // 导致计数变为了 0
        ExecutorService service = Executors.newFixedThreadPool(2);
        CyclicBarrier barrier = new CyclicBarrier(2, () -> {
            log.debug("task1, task2 finish...");
        });

        service.submit(() -> {
           log.debug("task1 begin...");
           sleep(1000);
            try {
                barrier.await(); // 2 - 1 = 1
                log.debug("task1 end...");
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        });

        service.submit(() -> {
           log.debug("task2 begin...");
           sleep(2000);
            try {
                barrier.await(); // 1 - 1 = 0 当变为0后下次计算又是2 可以重复使用而 countDownLatch 则不行
                log.debug("task2 end...");
            } catch (InterruptedException | BrokenBarrierException e) {
                e.printStackTrace();
            }
        });

        service.shutdown();
    }

    private static void sleep(int mills) {
        try {
            Thread.sleep(mills);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
